/**
 * Copyright 2018-2020 stylefeng & fengshuonan (sn93@qq.com)
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.asen.gateway.filter;

import com.asen.gateway.constants.FilterConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 请求路径权限过滤器
 *
 * @author: menggangaaa
 * @Date: 2022/04/19
 */
@Slf4j
@Component
@Order(FilterConstant.PATH_MATCH_FILTER_ORDER)
public class PathMatchFilter implements GlobalFilter, Ordered {
    enum FilterEnum {
        // 用户登录和token相关url
        LOGIN_TOKEN_URL,
        // 不登录可直接访问
        DIRECT,
        // 跳过授权,登录即可访问
        SKIP_AUTH,
        // 管理员admin
        ADMIN,
        // 需要授权
        CHECK_AUTH
    }

    //@Autowired
    //private TokenValidateService tokenValidateService;
    //
    //@Autowired
    //private WhitelistChecker whitelistChecker;

    @Override
    public int getOrder() {
        return FilterConstant.PATH_MATCH_FILTER_ORDER;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        /*ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        try {
            Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
            String schema = route.getUri().getScheme();
            String serviceName = "lb".equals(schema) ? route.getUri().getHost() : null;

            // 判断请求的过滤类型
            FilterEnum filterType = this.filterType(request, serviceName, request.getURI().getPath());

            if (filterType == FilterEnum.LOGIN_TOKEN_URL) {
                // 用户登录和token相关url
            } else if (filterType == FilterEnum.DIRECT) {
                // 不登录可直接访问，默认虚拟一个token
                //exchange = this.handleDirect(exchange);
            } else if (filterType == FilterEnum.SKIP_AUTH) {
                // 跳过授权,登录即可访问
            } else if (filterType == FilterEnum.ADMIN) {
                // 管理员admin
            } else if (filterType == FilterEnum.CHECK_AUTH) {
                // 需要授权
                Set<URI> originalRoute = exchange.getAttribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR);
                URI uri = null;
                if (CollectionUtils.isNotEmpty(originalRoute)) {
                    uri = originalRoute.iterator().next();
                }
                this.handleCheckAuth(request, uri);
            }
        } catch (Exception e) {
            log.error("Gateway过滤器[PathMatchFilter]异常:", e);
            ApiResult result = ApiResultUtils.parse(e);
            result.setMessage(e.getMessage());
            // 拦截并发送消息返回前端
            return GatewayUtil.handleResponse(response, result);
        }*/
        return chain.filter(exchange);
    }

    /**
     * 请求URL过滤类型
     */
    /*private FilterEnum filterType(ServerHttpRequest request, String serviceName, String servletPath) {
        // 将路径截取,比如上传文件类型"/zuul"等
        String url = interceptUrl(servletPath);
        // 获取登录token
        String token = GatewayUtil.getToken(request);

        // 验证 用户登录和token相关url
        if (whitelistChecker.checkIfIgnore(url)) {
            return FilterEnum.LOGIN_TOKEN_URL;
        }

        // 验证 工作流引擎跳过权限配置
        if (whitelistChecker.checkWorkflow(url)) {
            return FilterEnum.SKIP_AUTH;
        }

        // 验证 不登录可直接访问
        if (whitelistChecker.checkIfDirectAccess(serviceName, url)) {
            return FilterEnum.DIRECT;
        }

        // 验证 不登录可直接访问
        if (whitelistChecker.checkIfDirectAccessLc(serviceName, url, token)) {
            return FilterEnum.DIRECT;
        }

        // 验证 是否管理员登录
        if (tokenValidateService.checkIsAdmin(token)) {
            return FilterEnum.ADMIN;
        }

        // 验证 跳过授权,登录即可访问
        if (whitelistChecker.checkIfLoginAccess(serviceName, url, token)) {
            return FilterEnum.SKIP_AUTH;
        }

        // 需要授权
        return FilterEnum.CHECK_AUTH;
    }*/

    /**
     * 处理 不登录可直接访问
     */
    /*private ServerWebExchange handleDirect(ServerWebExchange exchange) {
        ServerHttpRequest request = exchange.getRequest();
        // 不登录可直接访问，默认虚拟一个token
        String token = GatewayUtil.getToken(request);
        // 从参数或header中获取租户id
        Long tenantId = GatewayUtil.getTenantId(request);
        if (StringUtils.isBlank(token) || tokenValidateService.isTokenExpired(token)) {
            // 请求中不存在token或者token超时,构建一个虚拟token
            request = GatewayUtil.genHeadToken(request, tenantId);
            exchange = exchange.mutate().request(request).response(exchange.getResponse()).build();
        }
        return exchange;
    }*/

    /**
     * 处理 需要授权
     */
    /*private void handleCheckAuth(ServerHttpRequest request, URI uri) {
        // 获取当前url
        Long startTime = System.currentTimeMillis();
        if (uri == null) {
            uri = request.getURI();
        }
        log.info("本次前端访问的路径为: {}", uri);
        String url = interceptUrl(uri.getPath());
        // 判断当前token是否存在
        String token = GatewayUtil.getToken(request);
        if (StringUtils.isBlank(token)) {
            throw new TokenInvalidException(BaseResultCode.E0003);
        }
        // 判断当前token对应用户是否包含请求的url对应权限
        if (!whitelistChecker.checkUrlCanAccess(url, token)) {
            // 用户不包含url的权限,则提示
            String urlName = whitelistChecker.getUrlName(url);
            String message = "用户没有URL[" + StringUtils.sure(urlName) + "][" + url + "]的访问权限";
            throw new IllegalLogicException(BaseResultCode.E0005, message);
        }
        Long endTime = System.currentTimeMillis();
        log.info("==========结束URL过滤器时间：" + endTime + "，耗时：" + (endTime - startTime) + "==========");
    }*/

}
